# -*- coding:utf-8 -*-
# import the necessary packages
from keras.preprocessing.image import img_to_array
from PIL import Image
import numpy as np
import settings
import helpers
import flask
import redis
import uuid
import time
import json
import io
import os

########### get current time #########
import datetime
def get_time_stamp():
    ct = time.time()
    local_time = time.localtime(ct)
    data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    data_secs = (ct -int(ct)) * 1000
    time_stamp = "%s.%03d" % (data_head, data_secs)
    return time_stamp
######################################

from flask import render_template, request, jsonify
 
# initialize our Flask application and Redis server 初始化Flask应用和Redis server
app = flask.Flask(__name__)
db = redis.StrictRedis(host=settings.REDIS_HOST,
    port=settings.REDIS_PORT, db=settings.REDIS_DB)
 
def prepare_image(image, target):
    # if the image mode is not RGB, convert it  图像预处理
    if image.mode != "RGB":
        image = image.convert("RGB")
 
    # resize the input image and preprocess it 更改输入图像的大小并处理
    image = image.resize(target)
    image = img_to_array(image)
    image = np.expand_dims(image, axis=0)

    # return the processed image 返回处理好的图像
    return image

project_path = os.path.dirname(os.path.realpath(__file__))
original_file_name = "original_{:%Y%m%dT%H%M%S}.png".format(datetime.datetime.now())
# original_file_name = "original.png"
# name_last = (original_file_name[9:-4])
original_file_path = os.path.join(project_path, "static", "images", "uploads", original_file_name)

@app.route("/", methods=['GET'])
def homepage():
    return render_template('index.html')
 
@app.route("/predict", methods=["GET", "POST"])
def predict():
    # initialize the data dictionary that will be returned from the
    # view 初始化从视图返回的数据字典
    data = {"success": False}
    # ensure an image was properly uploaded to our endpoint 确保图像被正确地加载到端点
    if flask.request.method == "POST":
        if flask.request.files.get("file"):
            # read the image in PIL format and prepare it for
            # classification 以PIL格式读入图像，准备分类
            image = flask.request.files["file"].read()
            image = Image.open(io.BytesIO(image))
            image.save(original_file_path)

            image_size = image.size

            image = prepare_image(image,
                (image_size[0], image_size[1]))

            img_input_W = str(image_size[0])
            img_input_H = str(image_size[1])
            # set product_selected initial value to [Creator 010: 5997ef035e0cc.jpg]
            # if 'product_name' not in vars():
            # product_name = "5997ef035e0cc.jpg"

            '''
            # ensure our NumPy array is C-contiguous as well,
            # otherwise we won't be able to serialize it            
            '''
            image = image.copy(order="C")
            # generate an ID for the classification then add the
            # classification ID + image to the queue
            k = str(uuid.uuid4())
            image = helpers.base64_encode_image(image)
            # d = {"id": k, "image": image, "width": img_input_W, "height": img_input_H, "product_selected": product_name}
            d = {"id": k, "image": image, "width": img_input_W, "height": img_input_H}
            db.rpush(settings.IMAGE_QUEUE, json.dumps(d))
 
            # keep looping until our model server returns the output
            # predictions  循环，直到模型服务器返回结果
            while True:
                # attempt to grab the output predictions 获取预测结果
                output = db.get(k)
 
                # check to see if our model has classified the input
                # image  检查看是否模型已经把输入图片分好类了
                if output is not None:
                    # add the output predictions to our data
                    # dictionary so we can return it to the client
                    # 把输出结果返回给数据字典，返回给客户端
                    output = output.decode("utf-8")
                    # data["predictions"] = json.loads(output)
                    data = json.loads(output)
                    print("\t **** data output: ", data)
                    # delete the result from the database and break
                    # from the polling loop 从数据库删除结果，退出循环
                    db.delete(k)
                    break
 
                # sleep for a small amount to give the model a chance
                # to classify the input image 等待模型对输入图像进行识别
                time.sleep(settings.CLIENT_SLEEP)
 
            # indicate that the request was a success  设置请求成功
            #data["success"] = True
            # result = str(data)
            # print(data[0]["score"])
            if data[0]["score"] == 0.0: result = "无结果,调低阈值,再试试?"
            else: result = "低俗"

            # result = str(data['predictions'][0]['splashed_path'])
            return result

    # return the data dictionary as a JSON response 返回JSON格式的数据字典

    # if flask.request.method == "GET":
    #     if flask.request.args.get('product_img_name', 0, type=str):
    #         product_name = request.args.get('product_img_name', 0, type=str)
    #
    #         image = Image.open(original_file_path)
    #
    #         image_size = image.size
    #
    #         image = prepare_image(image,
    #                               (image_size[0], image_size[1]))
    #
    #         img_input_W = str(image_size[0])
    #         img_input_H = str(image_size[1])
    #         # set product_selected initial value to [Creator 010: 5997ef035e0cc.jpg]
    #
    #         '''
    #         # ensure our NumPy array is C-contiguous as well,
    #         # otherwise we won't be able to serialize it
    #         '''
    #         image = image.copy(order="C")
    #         # generate an ID for the classification then add the
    #         # classification ID + image to the queue
    #         k = str(uuid.uuid4())
    #         image = helpers.base64_encode_image(image)
    #         d = {"id": k, "image": image, "width": img_input_W, "height": img_input_H, "product_selected": product_name}
    #         db.rpush(settings.IMAGE_QUEUE, json.dumps(d))
    #         # print("\nsaved to DB!")
    #         # keep looping until our model server returns the output
    #         # predictions  循环，直到模型服务器返回结果
    #         while True:
    #             # attempt to grab the output predictions 获取预测结果
    #             output = db.get(k)
    #
    #             # check to see if our model has classified the input
    #             # image  检查看是否模型已经把输入图片分好类了
    #             if output is not None:
    #                 # add the output predictions to our data
    #                 # dictionary so we can return it to the client
    #                 # 把输出结果返回给数据字典，返回给客户端
    #                 output = output.decode("utf-8")
    #                 data["predictions"] = json.loads(output)
    #
    #                 # delete the result from the database and break
    #                 # from the polling loop 从数据库删除结果，退出循环
    #                 db.delete(k)
    #                 break
    #
    #             # sleep for a small amount to give the model a chance
    #             # to classify the input image 等待模型对输入图像进行识别
    #             time.sleep(settings.CLIENT_SLEEP)
    #
    #         # indicate that the request was a success  设置请求成功
    #         data["success"] = True
    #         result = str(data['predictions'][0]['splashed_path'])
    #         # print(result)
    #         result_json = {"result": result}
    #         # print(result_json)
    #         return jsonify(result_json)

# for debugging purposes, it's helpful to start the Flask testing
# server (don't use this for production
if __name__ == "__main__":
    print("* Starting web service...")
    app.run(debug = True, port = 5000)
